﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CRM.DataAccess.Entities;
using CRM.Business.Services;
using CRM.Encryption;
using System.Data;
using Telerik.Web.UI;
using System.Configuration;
using System.Globalization;

namespace Web.Invoice
{
    public partial class EditInvoice : System.Web.UI.Page
    {
        static bool Saved_state = false;
        static string prevPage = String.Empty;
        static string requestEdit = string.Empty;
        static string itemID = string.Empty;
        static long InvID;
        static USER user;
        static int rowIndex = 0;
        static long? assignedToID = null;
        static ROLE r;
        static double[,] arr;
        static int size;
        protected void Page_Load(object sender, EventArgs e)
        {
            Saved_state = false;
            if (IsPostBack)
                return;
            assignedToID = null;
            if (Request.UrlReferrer != null)
            {
                prevPage = Request.UrlReferrer.ToString();
                hdntxtPrevPage.Value = prevPage;
            }
            user = (USER)Session["User"];
            if (user != null)
            {
                rowIndex = 0;
                r = RoleService.GetRoleByID((long)user.ROLE_ID);
                if ((!(bool)user.IS_ADMIN) && (!(bool)r.IS_MANAGER))
                {
                    assignedToID = user.ID;
                    divAssignTo.Visible = false;
                }

                requestEdit = Request.QueryString["id"];
                if (requestEdit != null)
                {
                    InvID = Convert.ToInt64(requestEdit);
                    LoadAllUser();
                    LoadAllDescription();
                    LoadAllTAC();
                    LoadInvoiceStatus();
                    LoadInvoiceInfo(Convert.ToInt64(requestEdit));
                    hdntxtInvoiceID.Value = requestEdit;
                    hdntxtPrint.Value = "0";
                }
            }
        }
        private void LoadInvoiceInfo(long invoiceID)
        {
            INVOICE_DETAIL invoiceDetail = InvoiceService.GetInvoiceDetailByID(invoiceID, assignedToID);
            
            if (invoiceDetail != null)
            {
                itemID = invoiceDetail.ITEM_ID.ToString();
                ////Invoice Details
                txtOrganizationName.Text = invoiceDetail.ORGANIZATION_NAME;
                hdntxtOrgName.Value = invoiceDetail.ORGANIZATION_NAME;
                hdntxtOrgID.Value = invoiceDetail.OrgID.ToString();
                txtContactName.Text = invoiceDetail.CONTACT_NAME;
                hdntxtConID.Value = invoiceDetail.CONTACT_ID.ToString();
                hdntxtConName.Value = invoiceDetail.CONTACT_NAME;
                txtCustomerNo.Text = invoiceDetail.CUSTOMER_NO;
                if (invoiceDetail.STATUS_ID != null)
                    ddlStatus.FindItemByValue(invoiceDetail.STATUS_ID.ToString()).Selected = true;
                dpInvoiceDate.SelectedDate = invoiceDetail.INVOICE_DATE;
                dpDueDate.SelectedDate = invoiceDetail.DUE_DATE;
                txtPurchaseOrder.Text = invoiceDetail.PURCHASE_ORDER;
                rntxtCommission.Value = invoiceDetail.SALES_COMMISSION;
                RadComboBoxItem ass = ddlAssignedTo.FindItemByValue(invoiceDetail.ASSIGN_TO_ID.ToString());
                if (ass != null)
                {
                    ddlAssignedTo.ClearSelection();
                    ass.Selected = true;
                }
                //////Adress Detail
                txtOfficeAddress.Text = invoiceDetail.OFFICE_ADDRESS;
                txtHome.Text = invoiceDetail.HOME_ADDRESS;
                txtOfficePOBox.Text = invoiceDetail.OFFICE_PO_BOX;
                txtHomePOBox.Text = invoiceDetail.HOME_PO_BOX;
                txtOfficeCity.Text = invoiceDetail.OFFICE_CITY;
                txtHomeCity.Text = invoiceDetail.HOME_CITY;
                txtOfficeState.Text = invoiceDetail.OFFICE_STATE;
                txtHomeState.Text = invoiceDetail.HOME_STATE;
                txtOfficePostalCode.Text = invoiceDetail.OFFICE_POSTAL_CODE;
                txtHomePostalCode.Text = invoiceDetail.HOME_POSTAL_CODE;
                txtOfficeCountry.Text = invoiceDetail.OFFICE_COUNTRY;
                txtHomeCountry.Text = invoiceDetail.HOME_COUNTRY;
                //Terms & Conditions
                if (invoiceDetail.TERMS_CONDITIONS_ID != null)
                {
                    ddlTermsAndConditions.FindItemByValue(invoiceDetail.TERMS_CONDITIONS_ID.ToString()).Selected = true;
                    TERMS_AND_CONDITIONS tac = TermsAndConditionsService.GetTACByID(Convert.ToInt64(invoiceDetail.TERMS_CONDITIONS_ID));
                    txtTermsAndConditions.Text = tac.DESCRIPTION;
                }

                //Description Details
                if (invoiceDetail.DESCRIPTION_ID != null)
                {
                    ddlDescriptions.FindItemByValue(invoiceDetail.DESCRIPTION_ID.ToString()).Selected = true;
                    DESCRIPTION_DETAILS dd = DescriptionDetailService.GetDescriptionByID(Convert.ToInt64(invoiceDetail.DESCRIPTION_ID));
                    txtDescriptions.Text = dd.DESCRIPTION;
                }
                //Item Details
                if (ViewState["Products"] == null)
                {
                    DataTable dt = new DataTable();
                    dt.Columns.Add(new DataColumn("ID"));
                    dt.Columns.Add(new DataColumn("ITEM_ID"));
                    dt.Columns.Add(new DataColumn("ITEM_DETAIL_ID"));
                    dt.Columns.Add(new DataColumn("ProductID"));
                    dt.Columns.Add(new DataColumn("ProductName"));
                    dt.Columns.Add(new DataColumn("ProductDescription"));
                    dt.Columns.Add(new DataColumn("GST", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("Quantity", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("Balance", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("CurrentBalance", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("Image"));
                    dt.Columns.Add(new DataColumn("UnitPrice", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("DiscountPrice", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("DiscountPercent", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("TotalPrice", typeof(System.Double)));
                    dt.Columns.Add(new DataColumn("DiscountType"));
                    ViewState["Products"] = GetItemListDataTable(invoiceDetail.ITEM_ID, dt);
                    rowIndex = dt.Rows.Count;
                }
            }
            else
            {
                divContent.Style["display"] = "none";
                divError.Style["display"] = "block";
                
            }
        }

        protected void SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ddlDescriptions.SelectedValue != "-1")
            {
                DESCRIPTION_DETAILS dd = DescriptionDetailService.GetDescriptionByID(Convert.ToInt64(ddlDescriptions.SelectedValue));
                txtDescriptions.Text = dd.DESCRIPTION;
            }
            if (ddlTermsAndConditions.SelectedValue != "-1")
            {
                TERMS_AND_CONDITIONS tac = TermsAndConditionsService.GetTACByID(Convert.ToInt64(ddlTermsAndConditions.SelectedValue));
                txtTermsAndConditions.Text = tac.DESCRIPTION;
            }
        }
        private DataTable GetItemListDataTable(long? itemID, DataTable dt)
        {
            List<ITEM_DETAILS> itemDetails = ItemService.GetListItemDetailByItemID(itemID);
            if (itemDetails != null)
            {
                size = itemDetails.Count;
                arr = new double[2, size];
                for (int i = 0; i < size; i++)
                {
                    arr[0, i] = itemDetails[i].PRODUCT_ID;
                    arr[1, i] = Convert.ToDouble(itemDetails[i].QUANTITY.ToString());
                }
                for (int i = 0; i < size; i++)
                {
                    for (int j = i + 1; j < size; j++)
                    {
                        if (arr[0, i] == arr[0, j])
                        {
                            arr[1, i] += arr[1, j];
                            arr[1, j] = 0;
                        }
                    }
                }
                rowIndex = itemDetails.Count;
                for (int i = 0; i < itemDetails.Count; i++)
                {
                    ITEM_DETAILS item = itemDetails[i];
                    DataRow dr = dt.NewRow();
                    dr["ID"] = i;
                    dr["ITEM_ID"] = item.ITEM_ID;
                    dr["ITEM_DETAIL_ID"] = item.ITEM_DETAIL_ID;
                    dr["ProductID"] = item.PRODUCT_ID.ToString();
                    dr["ProductDescription"] = item.DESCRIPTION;
                    dr["GST"] = item.GST_PERCENT == null ? 0 : item.GST_PERCENT;
                    dr["ProductName"] = item.PRODUCT_NAME;
                    dr["Quantity"] = item.QUANTITY;
                    dr["Balance"] = item.BALANCE + arr[1, i];
                    dr["CurrentBalance"] = item.BALANCE + arr[1, i] - item.QUANTITY;
                    dr = updatevalue(dr, dt);
                    dr["Image"] = item.IMAGE;
                    dr["UnitPrice"] = item.UNIT_PRICE;
                    dr["DiscountPrice"] = item.DISCOUNT_PRICE;
                    dr["DiscountPercent"] = item.DISCOUNT_PERCENT;
                    if (item.DISCOUNT_PERCENT != 0)
                        dr["DiscountType"] = "Per";
                    else if (item.DISCOUNT_PRICE != 0)
                        dr["DiscountType"] = "Pri";
                    else
                        dr["DiscountType"] = "Per";
                    dr["TotalPrice"] = item.PRICE;
                    dt.Rows.Add(dr);
                }
            }
            return dt;
        }
        private DataRow updatevalue(DataRow dr, DataTable dt)
        {
            if (dt != null)
            {
                for (int i = Convert.ToInt32(dr["ID"].ToString()) - 1; i >= 0; i--)
                {
                    if (dt.Rows[i]["ProductID"].ToString() == dr["ProductID"].ToString())
                    {
                        dr["Balance"] = Convert.ToDouble(dt.Rows[i]["CurrentBalance"]);
                        dr["CurrentBalance"] = Convert.ToDouble(dr["Balance"].ToString()) - Convert.ToDouble(dr["Quantity"].ToString());
                        break;
                    }
                }
            }
            return dr;
        }
        private DataTable AddRow(DataTable dt)
        {
            DataRow dr = dt.NewRow();
            // get list cac item cua Invoice ID nay
            //PRODUCT p = ProductService.GetTop1Product(assignedToID);
            //if (p != null)
            {
                // dung cho nay de bind ra luoi item deatail
                dr["ID"] = rowIndex;
                dr["ProductID"] = -1;
                dr["ProductDescription"] = "";
                dr["GST"] = 0;
                dr["ProductName"] = "";
                dr["Quantity"] = 0;
                dr["Balance"] = 0;
                dr["CurrentBalance"] = 0;
                dr["Image"] = "../ProductImages/no_image_for_this_product.gif";
                dr["UnitPrice"] = 0;
                dr["DiscountPrice"] = 0;
                dr["DiscountPercent"] = 0;
                dr["DiscountType"] = "Per";
                dr["TotalPrice"] = 0;
                //dr = updatevalue(dr, dt);
                dt.Rows.Add(dr);
                rowIndex++;
            }
            // else
            //{
            //    RadAjaxManager.GetCurrent(this).ResponseScripts.Add(@"ShowMessage('" + "Do not have any product, please add new one first !" + "');");
            //    //MessageBox.Show(this.Page, Page.GetType(), "Do not have any products, please add new product !", "");
            //}
            return dt;
        }
        private void LoadAllUser()
        {
            ddlAssignedTo.Items.Clear();
            List<USER> users = UserService.ListAll();
            if (users != null)
            {
                foreach (USER u in users)
                {
                    ddlAssignedTo.Items.Add(new RadComboBoxItem(u.SUR_NAME + " " + u.NAME, u.ID.ToString()));
                }
            }
        }
        private void LoadInvoiceStatus()
        {
            ddlStatus.DataSource = InvoiceService.GetAllInvoiceStatus();
            ddlStatus.DataBind();
            ddlStatus.Items.Insert(0, new RadComboBoxItem("Select an option", "-1"));
        }
        private void LoadAllDescription()
        {
            ddlDescriptions.DataSource = DescriptionDetailService.GetAllDescriptionDetails();
            ddlDescriptions.DataBind();
            ddlDescriptions.Items.Insert(0, new RadComboBoxItem("Select an option", "-1"));
        }
        private void LoadAllTAC()
        {
            ddlTermsAndConditions.DataSource = TermsAndConditionsService.GetAllTAC();
            ddlTermsAndConditions.DataBind();
            ddlTermsAndConditions.Items.Insert(0, new RadComboBoxItem("Select an option", "-1"));
        }
        protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridPagerItem)
            {
                GridPagerItem oGridPagerItem = (GridPagerItem)e.Item;
                RadComboBox oRadComboBox = (RadComboBox)oGridPagerItem.FindControl("PageSizeComboBox");
                oRadComboBox.Width = Unit.Pixel(50);
            }
            if (e.Item is GridDataItem)
            {
                GridDataItem item = (GridDataItem)e.Item;
                LinkButton lbtnProductSearch = (LinkButton)item.FindControl("lbtnProductSearch");
                LinkButton lbtnProductClear = (LinkButton)item.FindControl("lbtnProductClear");
                lbtnProductSearch.OnClientClick = string.Format("return openProductSearchWindow('{0}')", e.Item.ItemIndexHierarchical);
           //     lbtnProductClear.OnClientClick = string.Format("return clearProductName('{0}')", e.Item.ItemIndexHierarchical);
            }
        }
        private int updateInvoice()
        {
            INVOICE oldInvoice = InvoiceService.GetInvoiceByID(Convert.ToInt64(requestEdit));
            ITEM item = ItemService.GetItemByID(oldInvoice.ITEM_ID);
            if (item == null)
                item = new ITEM();
            INVOICE invoice = new INVOICE();
            invoice.ID = oldInvoice.ID;
            DateTime dt = DateTime.Now;
            invoice.DATE_MODIFIED = dt;
            invoice.DATE_ENTERED = oldInvoice.DATE_ENTERED;
            invoice.INVOICE_NUMBER = oldInvoice.INVOICE_NUMBER;
            // Invoice Details
            invoice.CUSTOMER_NO = txtCustomerNo.Text.Trim();
            if (hdntxtConID.Value != "")
                invoice.CONTACT_ID = Convert.ToInt64(hdntxtConID.Value);
            invoice.INVOICE_DATE = dpInvoiceDate.SelectedDate;
            invoice.DUE_DATE = dpDueDate.SelectedDate;
            invoice.PURCHASE_ORDER = txtPurchaseOrder.Text.Trim();
            invoice.SALES_COMMISSION = rntxtCommission.Value;
            if (hdntxtOrgID.Value != "")
                invoice.ORGANIZATION_ID = Convert.ToInt64(hdntxtOrgID.Value);
            if (ddlStatus.SelectedValue != "-1")
                invoice.STATUS_ID = Convert.ToInt64(ddlStatus.SelectedValue);

            if ((!(bool)user.IS_ADMIN) && (!(bool)r.IS_MANAGER))
                invoice.ASSIGNED_TO = user.ID;
            else
                if (ddlAssignedTo.SelectedItem != null)
                    invoice.ASSIGNED_TO = Convert.ToInt64(ddlAssignedTo.SelectedValue);

            invoice.SAVED_STATE = Saved_state;

            // Address Details
            invoice.OFFICE_ADDRESS = txtOfficeAddress.Text.Trim();
            invoice.HOME_ADDRESS = txtHome.Text.Trim();
            invoice.OFFICE_PO_BOX = txtOfficePOBox.Text.Trim();
            invoice.HOME_PO_BOX = txtHomePOBox.Text.Trim();
            invoice.OFFICE_CITY = txtOfficeCity.Text.Trim();
            invoice.HOME_CITY = txtHomeCity.Text.Trim();
            invoice.OFFICE_STATE = txtOfficeState.Text.Trim();
            invoice.HOME_STATE = txtHomeState.Text.Trim();
            invoice.OFFICE_POSTAL_CODE = txtOfficePostalCode.Text.Trim();
            invoice.HOME_POSTAL_CODE = txtHomePostalCode.Text.Trim();
            invoice.OFFICE_COUNTRY = txtOfficeCountry.Text.Trim();
            invoice.HOME_COUNTRY = txtHomeCountry.Text.Trim();
            //invoice.ITEM_ID = itemID;
            // Terms & Conditions
            if (ddlDescriptions.SelectedValue != "-1")
                invoice.DESCRIPTION_ID = Convert.ToInt64(ddlDescriptions.SelectedValue);
            // Description Details
            if (ddlTermsAndConditions.SelectedValue != "-1")
                invoice.TERMS_CONDITIONS_ID = Convert.ToInt64(ddlTermsAndConditions.SelectedValue);
            // Item Detail
            //ITEM item = new ITEM();
            List<ITEM_DETAIL> Litems = GetItemList(ref item);
            item.DATE_MODIFIED = dt;
            return InvoiceService.UpdateInvoice(invoice, item, Litems);
        }
        protected void btn_SaveAsDraft_Click(object sender, EventArgs e)
        {
            Saved_state = false;
            RadGrid1.Rebind();
            int updateInv = updateInvoice();
            if (updateInv == 1)
            {
                RadAjaxManager.GetCurrent(this).ResponseScripts.Add(@"ShowMessageAndRedirect('" + "Update invoice successful !" + "','" + "Invoices.aspx" + "');");
                hdntxtPrint.Value = "1";
            }
            else
                RadAjaxManager.GetCurrent(this).ResponseScripts.Add(@"ShowMessage('" + "Can not update this invoice !" + "');");
        }
        protected void btn_Save_Click(object sender, EventArgs e)
        {
            Saved_state = true;
            RadGrid1.Rebind();
            int updateInv = updateInvoice();
            if (updateInv == 1)
            {
                string path = "InvoiceReport.aspx?InvoiceID=" + InvID.ToString();
                ScriptManager.RegisterStartupScript(this, typeof(string), "Print", "radConfirmPrint('" + "Do you want to print it now? !" + "','" + path + "','Invoices.aspx');", true);
            }
            else
                RadAjaxManager.GetCurrent(this).ResponseScripts.Add(@"ShowMessage('" + "Can not update this invoice !" + "');");
        }
        private List<ITEM_DETAIL> GetItemList(ref ITEM i)
        {
            List<ITEM_DETAIL> re = new List<ITEM_DETAIL>();
            RadGrid1.AllowPaging = false;
            RadGrid1.Rebind();
            double? total_price = 0;
            foreach (GridDataItem item in RadGrid1.Items)
            {
                RadNumericTextBox rntxtQuantity = (RadNumericTextBox)item.FindControl("rntxtQuantity");
                RadNumericTextBox rntxtTotalPrice = (RadNumericTextBox)item.FindControl("rntxtTotalPrice");
                RadNumericTextBox rntxtDiscountPercent = (RadNumericTextBox)item.FindControl("rntxtDiscountPercent");
                RadNumericTextBox rntxtDiscountPrice = (RadNumericTextBox)item.FindControl("rntxtDiscountPrice");
                RadButton rbtnPercent = (RadButton)item.FindControl("rbtnPercent");
                RadNumericTextBox rntxtGST = (RadNumericTextBox)item.FindControl("rntxtGST");
                RadNumericTextBox rntxtUnitPrice = (RadNumericTextBox)item.FindControl("rntxtUnitPrice");
                ITEM_DETAIL d = new ITEM_DETAIL();
                d.PRODUCT_ID = Convert.ToInt64(item.GetDataKeyValue("ProductID"));
                d.QUANTITY = rntxtQuantity.Value;
                d.PRICE = rntxtTotalPrice.Value;
                d.DISCOUNT_PERCENT = rbtnPercent.Checked ? rntxtDiscountPercent.Value : 0;
                d.DISCOUNT_PRICE = rbtnPercent.Checked ? 0 : rntxtDiscountPrice.Value;
                d.GST = rntxtGST.Value;
                d.UNIT_PRICE = rntxtUnitPrice.Value;
                total_price += d.PRICE;
                re.Add(d);
            }
            i.TOTAL_PRICE = total_price;
            RadGrid1.AllowPaging = true;
            RadGrid1.Rebind();
            return re;
        }
        protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadGrid1.DataSource = dt;
        }
        protected void RadGrid1_ItemCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
        {
            GridDataItem item = e.Item as GridDataItem;
            if (e.CommandName == "Delete")
            {
                DataTable dt = (DataTable)ViewState["Products"];
                DataRow dr = null;
                foreach (DataRow r in dt.Rows)
                {
                    if (r["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                    {
                        if (dt != null)
                        {
                            for (int i = Convert.ToInt32(r["ID"].ToString()) + 1; i < dt.Rows.Count; i++)
                            {
                                if (dt.Rows[i]["ProductID"].ToString() == r["ProductID"].ToString())
                                {
                                    dt.Rows[i]["Balance"] = Convert.ToDouble(dt.Rows[i]["Balance"]) + Convert.ToDouble(r["Quantity"].ToString());
                                    double currentbalance = Convert.ToDouble(dt.Rows[i]["Balance"].ToString()) - Convert.ToDouble(dt.Rows[i]["Quantity"].ToString());
                                    if (currentbalance > 0)
                                        dt.Rows[i]["CurrentBalance"] = currentbalance;
                                    else
                                    {
                                        dt.Rows[i]["CurrentBalance"] = 0;
                                        dt.Rows[i]["Quantity"] = Convert.ToDouble(dt.Rows[i]["Balance"].ToString());
                                    }
                                }
                                dt.Rows[i]["ID"] = Convert.ToDouble(dt.Rows[i]["ID"].ToString()) - 1;
                            }
                        }
                        dr = r;
                        break;
                    }
                }
                if (dr != null)
                {
                    dt.Rows.Remove(dr);
                    rowIndex--;
                }
                dt.AcceptChanges();
                ViewState["Products"] = dt;
                RadGrid1.DataSource = dt;
                RadGrid1.DataBind();
            }
            if (e.CommandName == "Clear")
            {
                DataTable dt = (DataTable)ViewState["Products"];
              
                foreach (DataRow r in dt.Rows)
                {
                    if (r["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                    {
                        if (dt != null)
                        {
                            for (int i = Convert.ToInt32(r["ID"].ToString()) + 1; i < dt.Rows.Count; i++)
                            {
                                if (dt.Rows[i]["ProductID"].ToString() == r["ProductID"].ToString())
                                {
                                    dt.Rows[i]["Balance"] = Convert.ToDouble(dt.Rows[i]["Balance"]) + Convert.ToDouble(r["Quantity"].ToString());
                                    double currentbalance = Convert.ToDouble(dt.Rows[i]["Balance"].ToString()) - Convert.ToDouble(dt.Rows[i]["Quantity"].ToString());
                                    if (currentbalance > 0)
                                        dt.Rows[i]["CurrentBalance"] = currentbalance;
                                    else
                                    {
                                        dt.Rows[i]["CurrentBalance"] = 0;
                                        dt.Rows[i]["Quantity"] = Convert.ToDouble(dt.Rows[i]["Balance"].ToString());
                                    }
                                }

                            }

                        }
                       
                        {
                            r["ProductID"] = -1;
                            r["ProductDescription"] = "";
                            r["GST"] = 0;
                            r["ProductName"] = "";
                            r["Quantity"] = 0;
                            r["Balance"] = 0;
                            r["CurrentBalance"] = 0;
                            r["Image"] = "../ProductImages/no_image_for_this_product.gif";
                            r["UnitPrice"] = 0;
                            r["DiscountPrice"] = 0;
                            r["DiscountPercent"] = 0;
                            r["DiscountType"] = "Per";
                            r["TotalPrice"] = 0;
                        }

                      
                        break;
                    }
                }
               
                dt.AcceptChanges();
                ViewState["Products"] = dt;
                RadGrid1.DataSource = dt;
                RadGrid1.DataBind();
            }
        }

        protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            if (e.Item is GridDataItem)
            {
                GridDataItem item = e.Item as GridDataItem;
                System.Web.UI.WebControls.Image img = (System.Web.UI.WebControls.Image)item.FindControl("productImage");     
                TextBox txtProductName = (TextBox)item.FindControl("txtProductName");                
                TextBox txtProductDescription = (TextBox)item.FindControl("txtProductDescription");                
                RadButton rbtnPercent = (RadButton)item.FindControl("rbtnPercent");
                RadNumericTextBox rntxtGST = (RadNumericTextBox)item.FindControl("rntxtGST");
                RadNumericTextBox rntxtUnitPrice = (RadNumericTextBox)item.FindControl("rntxtUnitPrice");                
                RadButton rbtnPrice = (RadButton)item.FindControl("rbtnPrice");
                RadNumericTextBox rntxtQuantity = (RadNumericTextBox)item.FindControl("rntxtQuantity");
                RadNumericTextBox rntxtBalance = (RadNumericTextBox)item.FindControl("rntxtBalance");
                RadNumericTextBox rntxtCurrentBalance = (RadNumericTextBox)item.FindControl("rntxtCurrentBalance");
                Panel divDiscountPercent = (Panel)item.FindControl("divDiscountPercent");
                Panel divDiscountPrice = (Panel)item.FindControl("divDiscountPrice");
                RadNumericTextBox rntxtDiscountPercent = (RadNumericTextBox)item.FindControl("rntxtDiscountPercent");
                RadNumericTextBox rntxtDiscountPrice = (RadNumericTextBox)item.FindControl("rntxtDiscountPrice");
                RadNumericTextBox rntxtTotalPrice = (RadNumericTextBox)item.FindControl("rntxtTotalPrice");
                /////////////////////////
                rntxtQuantity.Attributes.Add("onclick", "Select('" + e.Item.ItemIndexHierarchical + "');");
                rntxtDiscountPercent.Attributes.Add("onclick", "Select('" + e.Item.ItemIndexHierarchical + "');");
                rntxtDiscountPrice.Attributes.Add("onclick", "Select('" + e.Item.ItemIndexHierarchical + "');");
                rntxtGST.Attributes.Add("onclick", "Select('" + e.Item.ItemIndexHierarchical + "');");
                rntxtUnitPrice.Attributes.Add("onclick", "Select('" + e.Item.ItemIndexHierarchical + "');");
                rbtnPercent.Attributes.Add("onclick", "Select('" + e.Item.ItemIndex + "');");
                rbtnPrice.Attributes.Add("onclick", "Select('" + e.Item.ItemIndex + "');");
                foreach (DataRow dr in dt.Rows)
                {
                    if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                    {
                        img.ImageUrl = dr["Image"].ToString();
                        txtProductDescription.Text = dr["ProductDescription"].ToString();
                        rntxtGST.Value = convertCurrencyToDouble(dr["GST"].ToString());
                        rntxtUnitPrice.Value = convertCurrencyToDouble(dr["UnitPrice"].ToString());

                        rbtnPrice.Checked = dr["DiscountType"].ToString() == "Pri" ? true : false;
                        rbtnPercent.Checked = dr["DiscountType"].ToString() == "Per" ? true : false;
                        rntxtQuantity.Value = Convert.ToDouble(dr["Quantity"].ToString());
                        rntxtBalance.Value = Convert.ToDouble(dr["Balance"].ToString());
                        rntxtCurrentBalance.Value = Convert.ToDouble(dr["CurrentBalance"].ToString());
                        rntxtDiscountPrice.Value = Convert.ToDouble(dr["DiscountPrice"].ToString());
                        rntxtDiscountPercent.Value = Convert.ToDouble(dr["DiscountPercent"].ToString());
                        if (dr["DiscountType"].ToString() == "Per")
                        {
                            divDiscountPercent.Style.Add("display", "block");
                            divDiscountPrice.Style.Add("display", "none");
                        }
                        else if (dr["DiscountType"].ToString() == "Pri")
                        {
                            divDiscountPercent.Style.Add("display", "none");
                            divDiscountPrice.Style.Add("display", "block");
                        }
                        rntxtTotalPrice.Value = Convert.ToDouble(dr["TotalPrice"].ToString());
                        // sum += rntxtTotalPrice.Value;
                        break;
                    }
                }
            }
            else if (e.Item is GridFooterItem)
            {
                double? sum = 0;
                GridFooterItem footer = (GridFooterItem)e.Item;
                RadNumericTextBox footeritem = (footer["TotalPrice"].FindControl("rntxtTotalPriceFooter") as RadNumericTextBox);
                if (footeritem != null)
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        sum += Convert.ToDouble(dr["TotalPrice"].ToString());
                    }
                    footeritem.Value = sum;
                }
            }
        }
        private double? getTotalPrice(double? unitprice, double? quantity, double? discountper, double? discountpri, double? gst)
        {
            double? total = 0;
            total = unitprice * quantity;
            total += total * gst / 100.0;
            if (discountper != null)
                total -= total * discountper / 100.0;
            else if (discountpri != null)
                total -= discountpri;
            if (total < 0) total = 0;
            return total;
        }
        private DataTable saveallvaluebeforeventfire(DataTable dt)
        {

            foreach (GridDataItem item in RadGrid1.Items)
            {

                TextBox txtProductDescription = (TextBox)item.FindControl("txtProductDescription");
                RadNumericTextBox rntxtGST = (RadNumericTextBox)item.FindControl("rntxtGST");
                System.Web.UI.WebControls.Image img = (System.Web.UI.WebControls.Image)item.FindControl("productImage");     
                RadNumericTextBox rntxtUnitPrice = (RadNumericTextBox)item.FindControl("rntxtUnitPrice");
                RadNumericTextBox rntxtQuantity = (RadNumericTextBox)item.FindControl("rntxtQuantity");
                RadNumericTextBox rntxtBalance = (RadNumericTextBox)item.FindControl("rntxtBalance");
                RadNumericTextBox rntxtCurrentBalance = (RadNumericTextBox)item.FindControl("rntxtCurrentBalance");
                RadNumericTextBox rntxtDiscountPercent = (RadNumericTextBox)item.FindControl("rntxtDiscountPercent");
                RadNumericTextBox rntxtDiscountPrice = (RadNumericTextBox)item.FindControl("rntxtDiscountPrice");
                RadNumericTextBox rntxtTotalPrice = (RadNumericTextBox)item.FindControl("rntxtTotalPrice");
                RadButton rbtnPercent = (RadButton)item.FindControl("rbtnPercent");

                foreach (DataRow dr in dt.Rows)
                {
                    if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                    {
                        dr["Quantity"] = rntxtQuantity.Value;
                        dr["Balance"] = rntxtBalance.Value;
                        dr["CurrentBalance"] = rntxtCurrentBalance.Value;
                        dr["DiscountType"] = rbtnPercent.Checked ? "Per" : "Pri";
                        dr["DiscountPrice"] = rbtnPercent.Checked ? 0 : rntxtDiscountPrice.Value;
                        dr["DiscountPercent"] = rbtnPercent.Checked ? rntxtDiscountPercent.Value : 0;
                        double? total = 0;
                        total = rbtnPercent.Checked ? getTotalPrice(rntxtUnitPrice.Value, rntxtQuantity.Value, rntxtDiscountPercent.Value, null, rntxtGST.Value) :
                            getTotalPrice(rntxtUnitPrice.Value, rntxtQuantity.Value, null, rntxtDiscountPrice.Value, rntxtGST.Value);
                        dr["Totalprice"] = total;

                        break;
                    }
                }
            }
            return dt;
        }
        private void setProductInfo()
        {
            GridDataItem item = RadGrid1.Items[Convert.ToInt32(hdntxtCurrentRow.Value)];
            DataTable dt = (DataTable)ViewState["Products"];
            //update all value change before event fire
            dt = saveallvaluebeforeventfire(dt);

            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    #region update balance
                    for (int i = Convert.ToInt32(dr["ID"].ToString()) + 1; i < dt.Rows.Count; i++)
                    {
                        if (dt.Rows[i]["ProductID"].ToString() == dr["ProductID"].ToString())
                        {
                            dt.Rows[i]["Balance"] = Convert.ToDouble(dt.Rows[i]["Balance"]) + Convert.ToDouble(dr["Quantity"].ToString());
                            double currentbalance = Convert.ToDouble(dt.Rows[i]["Balance"].ToString()) - Convert.ToDouble(dt.Rows[i]["Quantity"].ToString());
                            if (currentbalance > 0)
                                dt.Rows[i]["CurrentBalance"] = currentbalance;
                            else
                            {
                                dt.Rows[i]["CurrentBalance"] = 0;
                                dt.Rows[i]["Quantity"] = Convert.ToDouble(dt.Rows[i]["Balance"].ToString());
                            }
                        }
                    }
                    #endregion
                    dr["Image"] = hdntxtProductImage.Value;
                    dr["ProductID"] = hdntxtProductID.Value;
                    dr["ProductName"] = hdntxtProductName.Value;
                    dr["ProductDescription"] = hdntxtProductDes.Value;
                    dr["GST"] = convertCurrencyToDouble(hdntxtProductGST.Value);
                    dr["UnitPrice"] = convertCurrencyToDouble(hdntxtProductUnitPrice.Value);
                    bool hadover = false;
                    if (dt != null)
                    {
                        for (int i = Convert.ToInt32(dr["ID"].ToString()) - 1; i >= 0; i--)
                        {
                            if (dt.Rows[i]["ProductID"].ToString() == dr["ProductID"].ToString())
                            {
                                dr["Balance"] = Convert.ToDouble(dt.Rows[i]["CurrentBalance"]);
                                double currentbalance = Convert.ToDouble(dr["Balance"].ToString()) - Convert.ToDouble(dr["Quantity"].ToString());
                                if (currentbalance > 0)
                                    dr["CurrentBalance"] = currentbalance;
                                else
                                {
                                    dr["CurrentBalance"] = 0;
                                    dr["Quantity"] = Convert.ToDouble(dr["Balance"].ToString());
                                }
                                hadover = true;
                                break;
                            }
                        }
                    }
                    // neu nhin len ko co ai thi minh la thang moi nhat => + quantity trong arrray
                    double balance1 = 0;
                    if (hadover == false)
                    {
                        for (int i = 0; i < size; i++)
                        {
                            if (arr[0, i] == Convert.ToDouble(dr["ProductID"].ToString()))
                            {
                                balance1 = Convert.ToDouble(hdntxtProductBalance.Value) + arr[1, i];
                                dr["Balance"] = balance1;
                                break;
                            }
                        }
                        // neu nhin xuong trong arr khong co thi = p.Balance
                        if (balance1 == 0)
                        {
                            balance1 = Convert.ToDouble(hdntxtProductBalance.Value);
                            dr["Balance"] = hdntxtProductBalance.Value;
                        }
                        dr["CurrentBalance"] = Convert.ToDouble(dr["Balance"].ToString()) - Convert.ToDouble(dr["Quantity"].ToString());
                    }

                    double? totalchange = 0;
                    totalchange = getTotalPrice(Convert.ToDouble(dr["UnitPrice"].ToString()), Convert.ToDouble(dr["Quantity"].ToString()), Convert.ToDouble(dr["DiscountPercent"].ToString()), Convert.ToDouble(dr["DiscountPrice"].ToString()), Convert.ToDouble(dr["GST"].ToString()));
                    dr["Totalprice"] = totalchange;


                    // cap nhat lai gia tri nhung dong cung product ID ben duoi (balance, currentBalance, Quantity, total
                    if (dt != null)
                    {
                        for (int i = Convert.ToInt32(dr["ID"].ToString()) + 1; i < dt.Rows.Count; i++)
                        {
                            if (dt.Rows[i]["ProductID"].ToString() == dr["ProductID"].ToString())
                            {
                                double balance = Convert.ToDouble(dt.Rows[i]["Balance"].ToString()) - Convert.ToDouble(dr["Quantity"].ToString());
                                double currentbalance = balance - Convert.ToDouble(dt.Rows[i]["Quantity"].ToString());
                                if (balance > 0)
                                {
                                    dt.Rows[i]["Balance"] = balance;
                                    if (currentbalance > 0)
                                        dt.Rows[i]["CurrentBalance"] = currentbalance;
                                    else
                                    {
                                        dt.Rows[i]["CurrentBalance"] = 0;
                                        dt.Rows[i]["Quantity"] = Convert.ToDouble(dt.Rows[i]["Balance"].ToString());
                                        double? totalchange2 = 0;
                                        totalchange2 = getTotalPrice(Convert.ToDouble(dt.Rows[i]["UnitPrice"].ToString()), Convert.ToDouble(dt.Rows[i]["Quantity"].ToString()), Convert.ToDouble(dt.Rows[i]["DiscountPercent"].ToString()), Convert.ToDouble(dt.Rows[i]["DiscountPrice"].ToString()), Convert.ToDouble(dt.Rows[i]["GST"].ToString()));
                                        dt.Rows[i]["Totalprice"] = totalchange2;
                                    }
                                }
                                else
                                {
                                    dt.Rows[i]["Balance"] = 0;
                                    dt.Rows[i]["Quantity"] = 0;
                                    dt.Rows[i]["CurrentBalance"] = 0;
                                    dt.Rows[i]["Totalprice"] = 0;
                                }
                            }
                        }
                    }
                    break;
                }
            }
            dt.AcceptChanges();
            ViewState["Products"] = dt;
            RadGrid1.DataSource = dt;
            RadGrid1.DataBind();

        }
        private double? convertCurrencyToDouble(string str)
        {
            if (str != "")
                return Double.Parse(str, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, new CultureInfo("en-US"));
            return 0;
        }
        protected void btnAddProduct_ServerClick(object sender, EventArgs e)
        {
            //DataTable dt = GetAllRow();
            DataTable dt = (DataTable)ViewState["Products"];
            dt = AddRow(dt);
            ViewState["Products"] = dt;

            RadGrid1.DataSource = dt;
            RadGrid1.DataBind();
        }
        protected void rntxtDiscountPercent_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent.Parent as GridDataItem;
            RadButton rbtnPercent = (RadButton)item.FindControl("rbtnPercent");
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["DiscountType"] = rbtnPercent.Checked ? "Per" : "Pri";
                    dr["DiscountPercent"] = txt.Value;
                    break;
                }
            }
        }
        protected void rntxtDiscountPrice_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent.Parent as GridDataItem;
            RadButton rbtnPercent = (RadButton)item.FindControl("rbtnPercent");
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["DiscountType"] = rbtnPercent.Checked ? "Per" : "Pri";
                    dr["DiscountPrice"] = txt.Value;
                    break;
                }
            }
        }
        protected void rntxtBalance_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent as GridDataItem;
            RadNumericTextBox rntxtBalance = (RadNumericTextBox)item.FindControl("rntxtBalance");
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["Balance"] = txt.Value;
                    break;
                }
            }
        }
        protected void rntxtCurrentBalance_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent as GridDataItem;
            RadNumericTextBox rntxtCurrentBalance = (RadNumericTextBox)item.FindControl("rntxtCurrentBalance");
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["CurrentBalance"] = txt.Value;
                    break;
                }
            }
        }
        protected void rntxtQuantity_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent as GridDataItem;
            RadNumericTextBox rntxtCurrentBalance = (RadNumericTextBox)item.FindControl("rntxtCurrentBalance");
            RadNumericTextBox rntxtBalance = (RadNumericTextBox)item.FindControl("rntxtBalance");
            RadNumericTextBox rntxtTotalPrice = (RadNumericTextBox)item.FindControl("rntxtTotalPrice");
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["Quantity"] = txt.Value;
                    break;
                }
            }
        }
        protected void rntxtTotalPrice_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent as GridDataItem;

            RadButton rbtnPercent = (RadButton)item.FindControl("rbtnPercent");
            RadNumericTextBox rntxtUnitPrice = (RadNumericTextBox)item.FindControl("rntxtUnitPrice");
            RadNumericTextBox rntxtQuantity = (RadNumericTextBox)item.FindControl("rntxtQuantity");
            RadNumericTextBox rntxtDiscountPercent = (RadNumericTextBox)item.FindControl("rntxtDiscountPercent");
            RadNumericTextBox rntxtDiscountPrice = (RadNumericTextBox)item.FindControl("rntxtDiscountPrice");
            RadNumericTextBox rntxtGST = (RadNumericTextBox)item.FindControl("rntxtGST");

            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    double? totalprice = 0;
                    double? discountprice = 0;
                    totalprice = rntxtUnitPrice.Value * rntxtQuantity.Value;
                    totalprice = totalprice + totalprice * rntxtGST.Value / 100.0;
                    if (rbtnPercent.Checked)
                        discountprice = (totalprice * rntxtDiscountPercent.Value / 100.0);
                    else
                        discountprice = rntxtDiscountPrice.Value;
                    totalprice = totalprice - discountprice;
                    if (totalprice < 0) totalprice = 0;
                    dr["TotalPrice"] = totalprice;
                    break;
                }
            }
        }
        protected void btnCloseRadWin_ServerClick(object sender, EventArgs e)
        {
            if (hdntxtProductID.Value != "")
            {
                setProductInfo();
                hdntxtProductID.Value = "";
            }
        }

        protected void rntxtGST_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent.Parent as GridDataItem;
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["GST"] = txt.Value;
                    break;
                }
            }
        }

        protected void rntxtUnitPrice_TextChanged(object sender, EventArgs e)
        {
            DataTable dt = (DataTable)ViewState["Products"];
            RadNumericTextBox txt = sender as RadNumericTextBox;
            GridDataItem item = txt.Parent.Parent as GridDataItem;
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["ID"].ToString() == item.GetDataKeyValue("ID").ToString())
                {
                    dr["UnitPrice"] = txt.Value;
                    break;
                }
            }
        }

    }
}